<template>
  <!-- 执行计划页面 -->
  <div class="actionplan-info">
    <h2>
      {{ mapName }}
      <div class="action-back-but" v-if="routePath == '/plan'">
        <el-button type="danger" @click="stopPlan">停止执行计划</el-button>
        <el-button type="primary" @click="SuspendedTask()" v-show="shipStop">暂停任务</el-button>
        <el-button type="primary" @click="restoreTask()" v-show="!shipStop">恢复任务</el-button>
        <el-button type="primary" @click="immediatelyReturn()">立即返航</el-button>
        <!-- <el-button type="primary" @click="softReset()">无人船软复位</el-button> -->
      </div>
    </h2>
    <div class="actionplan-amap">
      <Amap
        :pointDataList="pointList"
        :routerTrackLine="routerTrackLine"
        :routerTrackLineTwo="routerTrackLineTwo"
        :targetDistance="targetDistance"
        :setmanned="setmanned"
        ref="amap"
      ></Amap>
      <!-- 组件引入 -->
      <!-- <amapleft :tableData="tableData"  ref="mapleft"></amapleft> -->
      <amapright
        class="amap-right"
        :setmanned="setmanned"
        :setMeasurement="setMeasurement"
        :usvName="usvName"
        ref="mapright"
      ></amapright>
      <div class="online-video">
        <OnlineVideo
          v-show="isShowVide"
          :accessToken="videoTokenData.token"
          :url="videoTokenData.url"
          :width="300"
          :height="200"
          ref="refOnlineVideo"
        ></OnlineVideo>
      </div>
      <!-- 障碍物坐标显示 -->
      <div class="actionplan-obstacles" v-if="obstaclesCoorFalse">
        <h6>附近障碍物坐标</h6>
        <li v-for="(coor, index) in obstaclesCoor" :key="index">
          <span v-for="(coors, index) in coor" :key="index">{{ coors }}</span>
        </li>
      </div>
      <el-button v-show="isShowVide" type="primary" @click="closeVideo" class="close-video">关闭监控</el-button>
      <el-button v-show="!isShowVide" type="primary" @click="openVideo" class="close-video">开启监控</el-button>
    </div>
  </div>
</template>

<script>
// 导入地图
import '@/plugins/amap';
import Amap from '@/amap/Amaps.vue';
import amapright from '@/components/plan/amap-information';
import { log } from 'util';
// 检查token是否过期
import { checkTokenTime } from '@/utils/common';
import { viewOnlineVideo, getOnlineVideoToken } from '@/utils/request'

import { stringify } from 'querystring';
import * as signalr from '@/utils/shioSignalR';
// 实时监控组件
import OnlineVideo from '@/components/video/OnlineVideo';
export default {
  name: 'actionplanInfo',
  components: {
    Amap,
    amapright,
    OnlineVideo
  },
  props: {
    planId: {
      type: String,
    },
    usvId: {
      type: String
    },
    routePath: {
      type: String
    },
  },
  data() {
    return {
      // 锚点
      pointList: [],
      // 船的单独信息
      setmanned: null,
      // 测量计划的信息
      setMeasurement: null,
      // 需要通过信息获取，接口没有问题就可以修改了
      tableData: [],
      // 当前计划名称
      mapName: '',
      // 船只名称
      usvName: '',
      // 定时器
      plantime: null,
      checkTokenInterval: null,
      TokenUpdateTime: null,
      // 障碍物坐标
      obstaclesCoor: [],
      // 轨迹绘制
      routerTrackLine: [],
      routerTrackLineTwo: [],
      // 模拟障碍物坐标
      obstaclesCoorFalse: '',
      // 当前坐标到下一个目标点的位置
      targetDistance: [],
      wsgLocation: {},
      // 停止执行计划
      shipStop: true,
      isShipStop: false,
      // 订阅id存储
      usvRuntimeInfoChangedId: '',
      planExecutionStateChangedId: '',
      wsConnectedCbHandle:0,
      // 是否显示diveo
      isShowVide: true,
      videoTokenData: {
        url: null,
        token: null,
        exp: null
      }
    };
  },
  computed: {},
  methods: {
    // ====================页面加载数据获取==================
    // 获取船信息
    getShipInfor(res) {
      // 不能存放相同的经纬度
      const isLine = this.routerTrackLine.some(item => {
        return res.location.longitude == item[0] && res.location.latitude == item[1];
      });
      if (!isLine) {
        // 无人船实时位置
        this.$set(this.routerTrackLine, this.routerTrackLine.length, [res.location.longitude, res.location.latitude]);
      }
      // 不能存放相同的第二条经纬度
      const isLineTwo = this.routerTrackLineTwo.some(item => {
        return res.calibratedLocation.longitude == item[0] && res.calibratedLocation.latitude == item[1];
      });
      if (!isLineTwo) {
        this.$set(this.routerTrackLineTwo, this.routerTrackLineTwo.length, [
          res.calibratedLocation.longitude,
          res.calibratedLocation.latitude
        ]);
      }
      // 调用方法，障碍坐标显示
      if (res.obstacleInfo) {
        this.obstaclesCoorFalse = res.obstacleInfo;
        this.setObstaclesCoor(res.obstacleInfo);
      }
      // 数据被赋值后，马上使用数据库的信息
      if (this.setMeasurement && this.pointList.length != 0) {
        if (this.setMeasurement.targetFix && this.routerTrackLine.length != 0) {
          // 将轨迹的最后一个坐标和获取到的指定信息路径存储做虚线指示
          this.targetDistance.splice(0, 1, this.routerTrackLineTwo[this.routerTrackLineTwo.length - 1]);
          this.targetDistance.splice(1, 1, [
            this.pointList[this.setMeasurement.targetFix - 1].location.longitude,
            this.pointList[this.setMeasurement.targetFix - 1].location.latitude
          ]);
        } else {
          this.targetDistance.splice(0, this.targetDistance.length - 1);
        }
      }
    },
    // 获取计划信息
    async getPlanInfor(res) {
      if (!res.errorCode) {
      } else {
        this.$message.error(res.message);
      }
    },
    // 关闭video
    closeVideo() {
      this.isShowVide = false;
      // 调用子组件的关闭方法
      this.$refs.refOnlineVideo.colseVideo();
    },
    // 开启video
    openVideo() {
      this.isShowVide = true;
      // 调用子组件的开启方法
      this.$refs.refOnlineVideo.openVideo();
    },
    // 转换为wgs坐标
    async wgsCoor(res) {
      if (res) {
        const { data: wsg } = await this.$http.get(
          `plan/convertcoordinate?coord=${res.runtimeInfo.location.latitude}%2C${res.runtimeInfo.location.longitude}&srid=wgs84`
        );
        if (!wsg.errorCode) {
          this.wsgLocation = { longitude: wsg.data.longitude, latitude: wsg.data.latitude };
        } else {
          this.$message.error(wsg.message);
        }
      }
    },
    // 获取计划标记点
    async getPlanCoor() {
      if (this.planId) {
        const { data: res } = await this.$http.get(`/plan/get?id=${this.planId}`);
        if (!res.errorCode) {
          // 排序获取信息
          res.data.fixes.sort(function (a, b) {
            return a.order - b.order;
          });
          this.pointList = res.data.fixes;
          this.mapName = res.data.name;
        } else {
          this.$message.error('未获取到当前计划信息');
        }
      } else if (this.routePath) {
        this.$message.warning('当前没有获取到计划id，默认显示第一个计划');
        const { data: res } = await this.$http.get(`/plan/query?Condition.Keyword=1&Page=1&Size=1`);
        if (!res.errorCode) {
          // 排序获取信息
          res.data.result[0].fixes.sort(function (a, b) {
            return a.order - b.order;
          });
          this.pointList = res.data.result[0].fixes;
          this.mapName = res.data.result[0].name;
        } else {
          this.$message.error('未获取到当前计划信息');
        }
      }
    },
    // 获取船只名字
    async getUsvName() {
      const { data: res } = await this.$http.get(`usv/get?id=${this.usvId}`);
      if (!res.errorCode) {
        this.usvName = res.data.displayName;
        //获取坐标信息后再执行地图自适应，此时数据才能获取到信息
        this.getRefsAmap();
      }
    },
    // 调用Usv接口做一个token更新
    async setTokenUpdata() {
      const { data: res } = await this.$http.get(`usv/get?id=${this.usvId}`);
    },
    // ======================通过signalr获取信息==========================
    // 同时获取两个信息用来做计算
    // twoPlan(refule) {
    //   if (this.usvId) {
    //     Promise.all([
    //       new Promise((resolve, reject) => {
    //         // 船信息
    //         this.$http
    //           .get(`usv/get?id=${this.usvId}`)
    //           .then(res => {
    //             resolve(res.data);
    //           })
    //           .catch(err => {
    //             reject(err);
    //           });
    //       }),
    //       new Promise((resolve, reject) => {
    //         // 计划信息
    //         this.$http
    //           .get(`plan/getexecutioncontext?usvId=${this.usvId}`)
    //           .then(res => {
    //             resolve(res.data);
    //           })
    //           .catch(err => {
    //             reject(err);
    //           });
    //       })
    //     ])
    //       .then(data => {
    //         this.setmanned = data[0].data;
    //         this.setMeasurement = data[1].data;
    //         // 当getExecutionContext接口返回状态码NotFound或执行状态为"已完成"时，应当停止刷新数据
    //         if (data[1].status == 'NotFound' || data[1].data.stage == 4) {
    //           window.clearInterval(this.plantime);
    //         }
    //         this.getShipInfor(data[0], refule);
    //         this.getPlanInfor(data[1]);
    //       })
    //       .catch(err => {
    //         this.$message.error(err);
    //       });
    //   } else {
    //     this.$message.info('船只id为正常传入，请重新执行计划尝试');
    //   }
    // },
    getUsvPlanInfo(reconnect) {
      var _this = this;
      function doSubscribe() {
        // 获取船只具体信息
        signalr.subscribe('usvRuntimeInfoChanged', _this.usvId, data => {
          if (data) {
            _this.setmanned = data;
            _this.getShipInfor(data);
          } else {
            this.$message.error('指定的无人船不存在或者用户没有访问指定无人船的权限!!');
          }
        }).then(codingId => {
          _this.usvRuntimeInfoChangedId = codingId;
        });
        // 获取计划详细信息
        signalr.subscribe('planExecutionStateChanged', _this.usvId, data => {
          if (data) {
            _this.setMeasurement = data;
            _this.getPlanInfor(data);
          } else {
            this.$message.error('指定的无人船不存在或者用户没有访问指定无人船的权限!!');
          }
        }).then(codingId => {
          _this.planExecutionStateChangedId = codingId;
        });
      }
      doSubscribe();
    },
    // 查看运行状态只需要一个信息
    getRunStateInfo(reconnect) {
      signalr.subscribe('usvRuntimeInfoChanged', this.usvId, data => {
        if (data) {
          this.setmanned = data;
          this.getShipInfor(data);
        } else {
          this.$message.error('指定的无人船不存在或者用户没有访问指定无人船的权限!!');
        }
      }).then(codingId => {
        this.usvRuntimeInfoChangedId = codingId;
      });
    },
    // 监测是否获取到地图并设置中心点
    getRefsAmap() {
      if (this.$route.path == '/viewrunstatus') {
        this.$refs.amap.onCompleted(x => this.$refs.amap.clickMapCenter());
      }
      if (this.$route.path == '/actionplan') {
        this.$refs.amap.onCompleted(x => this.$refs.amap.clickMapCenter());

        // // 进入页面优先地图自适应
        // this.$refs.amap.onCompleted(x => this.$refs.amap.setView());
      }
    },
    // =====================通过signalr获取信息结束====================
    // =====================页面加载获取信息结束====================
    // ========================计划操作开始========================
    // 停止计划==确认框弹出
    async stopPlan() {
      this.$confirm('是否停止该计划执行?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(data => {
          this.stopPlanFun();
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消停止计划'
          });
        });
    },
    // 停止任务==函数
    async stopPlanFun() {
      window.clearInterval(this.plantime);
      const { data: res } = await this.$http.post(`plan/cancel?usvId=${this.usvId}`);
      if (!res.errorCode) {
        let deletePath = this.$router.history.current.path;
        this.$store.commit('VueXDeleteTags', deletePath);
        this.$message.success('计划已经停止！');
        this.$router.go(-1);
      } else {
        this.$message.error(res.message);
      }
    },
    // 暂停任务
    async SuspendedTask() {
      const { data: res } = await this.$http.post(`/usv/pause?id=${this.setmanned.id}`);
      if (!res.errorCode) {
        console.log(res);
        this.shipStop = false;
      } else {
        this.$message.error('当前未有接口' + this.setmanned.id);
      }
    },
    // 恢复任务
    async restoreTask() {
      const { data: res } = await this.$http.post(`/usv/resume?id=${this.setmanned.id}`);
      if (!res.errorCode) {
        console.log(res);
        this.shipStop = true;
      } else {
        this.$message.error('当前未有接口' + this.setmanned.id);
      }
    },
    // 立即返航
    async immediatelyReturn() {
      const { data: res } = await this.$http.post(`/usv/return?id=${this.setmanned.id}`);
      if (!res.errorCode) {
        console.log(res);
      } else {
        this.$message.error('当前未有接口' + this.setmanned.id);
      }
    },
    // 无人船软复位
    async softReset() {
      const { data: res } = await this.$http.post(`/usv/reset?id=${this.setmanned.id}`);
      if (!res.errorCode) {
        console.log(res);
      } else {
        this.$message.error('当前未有接口' + this.setmanned.id);
      }
    },
    // =======================计划操作结束===================
    // =======================数据操作=======================
    // 障碍物信息拆分为二维数组
    setObstaclesCoor(str) {
      let splitArr = str.split('/');
      for (let arr of splitArr) {
        let arr2 = arr.split(',');
        for (let i in arr2) {
          arr2[i] = parseFloat(arr2[i]);
        }
        this.obstaclesCoor = [];
        this.$set(this.obstaclesCoor, this.obstaclesCoor.length, arr2);
      }
    }
    // ======================数据操作结束=======================
  },
  created() {
    console.log('被创建');
    this.getPlanCoor();
    this.getUsvName();
    // 5分钟获取一次token
    this.TokenUpdateTime = setInterval(() => {
      this.setTokenUpdata();
    }, 300000);
    // 页面加载时通过传过来的数据，进行数据获取
    if (this.routePath == '/plan') {
      this.wsConnectedCbHandle = signalr.connected(this.getUsvPlanInfo);
    } else {
      this.wsConnectedCbHandle = signalr.connected(this.getRunStateInfo);
    }
    viewOnlineVideo(this.usvId, this.videoTokenData)
    // 十秒检查一次token是否快过期,快过期给新的tokne
    this.checkTokenInterval = setInterval(() => {
      if (checkTokenTime(this.videoTokenData.exp, 3600)) {
        // 更新token的函数
        isShowVide && getOnlineVideoToken(this.videoTokenData)
      }
    }, 10000);
  },
  mounted() { },
  // 销毁当前实例清除掉定时器
  destroyed() {
    console.log('被销毁了');
    window.clearInterval(this.checkTokenInterval);
    window.clearInterval(this.TokenUpdateTime);
    if (this.routePath == '/plan') {
      signalr.unsubscribe([this.usvRuntimeInfoChangedId, this.planExecutionStateChangedId]);
    } else {
      signalr.unsubscribe([this.usvRuntimeInfoChangedId]);
    }

    signalr.unconnected(this.wsConnectedCbHandle);

    this.routerTrackLine = [];
    this.routerTrackLineTwo = [];
  },
  // 路由切换执行
  // beforeRouteEnter(to, from, next) {
  //   console.log('进入该路由');
  //   next(vm => {
  //     // 页面加载时通过传过来的数据，进行数据获取
  //     vm.getPlanCoor();
  //     vm.twoPlan(true);
  //     vm.plantime = setInterval(() => {
  //       vm.twoPlan();
  //     }, 3000);
  //   });
  // },
  // beforeRouteLeave(to, from, next) {
  //   console.log('离开该路由');
  //   console.log(to)
  //   console.log(from);
  //   clearInterval(this.plantime);
  //   next();
  // },
  watch: {}
};
</script>

<style lang="less" scoped>
li {
  list-style: none;
}
.actionplan-info {
  width: 100%;
  height: 100%;
  h2 {
    line-height: 50px;
    text-align: center;
    position: relative;

    .action-back-but {
      position: absolute;
      left: 0;
      top: 50%;
      z-index: 500;
      transform: translateY(-50%);
    }
  }
}
.actionplan-amap {
  width: 100%;
  height: calc(100% - 50px);
  position: relative;
}
.actionplan-obstacles {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}
.online-video {
  position: absolute;
  right: 0;
  top: 0;
}
// 实时视频的iframe样式
#ysopen {
  width: 300px;
  height: 200px;
}
.amap-right {
  width: calc(100% - 300px);
  height: auto;
}
.amap-right-plan {
  width: 100%;
  height: auto;
}
.close-video {
  position: absolute;
  bottom: 10px;
  right: 90px;
}
</style>
